package com.morningstar.authorization.config;

import cn.dev33.satoken.stp.SaTokenInfo;
import com.alibaba.fastjson.JSON;
import com.morningstar.authorization.controller.enitity.LoginEntity;
import com.morningstar.common.constants.QueueConstant;
import com.morningstar.common.logger.login.LoginLogger;
import com.morningstar.common.result.Result;
import com.morningstar.common.result.ResultCode;
import com.morningstar.system.api.feign.ISystemUserFeign;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.time.LocalDateTime;

import static com.morningstar.common.constants.HeaderConstants.*;

/**
 * @author Admin
 * 用户登录切面
 */
@Slf4j
@Aspect
@Component
public class LoginControllerAdvice {

    @Resource
    private ISystemUserFeign systemUserFeign;

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Pointcut("execution(* com.morningstar.authorization.controller.LoginController.login(..))")
    private void loginPointCut() {
    }

    @AfterReturning(value = "loginPointCut()", returning = "result")
    public void loginAfterReturning(JoinPoint joinPoint, Object result) {
        String requestIp = null;
        String browser = null;
        String os = null;
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (servletRequestAttributes != null) {
            HttpServletRequest httpServletRequest = servletRequestAttributes.getRequest();
            requestIp = httpServletRequest.getHeader(REQUEST_IP);
            browser = httpServletRequest.getHeader(REQUEST_BROWSER);
            os = httpServletRequest.getHeader(REQUEST_OS);
        }
        String loginName = null;
        Object[] getArgs = joinPoint.getArgs();
        Object arg = getArgs[0];
        if (arg instanceof LoginEntity loginEntity) {
            log.info("user login name {} login ip {}", loginEntity.getName(), requestIp);
            loginName = loginEntity.getName();
        }
        if (result instanceof Result<?> loginResult) {
            int code = loginResult.getCode();
            log.info("user login result {} login ip {}", code, requestIp);
            LoginLogger loginLogger = LoginLogger.builder()
                    .loginName(loginName)
                    .loginIp(requestIp)
                    .browser(browser)
                    .os(os)
                    .status(code)
                    .msg(loginResult.getMsg())
                    .loginTime(LocalDateTime.now())
                    .build();
            rabbitTemplate.convertAndSend(QueueConstant.LOGGER_LOGIN_QUEUE, JSON.toJSONString(loginLogger));
            if (code == ResultCode.SUCCESS.getStatus()) {
                SaTokenInfo saTokenInfo = (SaTokenInfo) loginResult.getData();
                systemUserFeign.userLoginSuccess(Long.parseLong(saTokenInfo.getLoginId().toString()), requestIp);
            }
        }
    }
}
